﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Resources;

/**
 * 创建时间：2014/11/6 17:34:47
 * 作者：yong.blackcore
 * Email：itblackhole@outlook.com
 * QQ：50404503
 */
namespace CUWo.Common
{
    /// <summary>     
    /// 独立存储缓存的图片源    
    /// <para>用法：</para>
    /// <para>定义图片控件或ImageSource：imageLocalCache</para>
    /// <para>后台代码：this.imageLocalCache.Source = new StorageCachedImage(new Uri("http://www.net.com/1.png"));</para>
    /// </summary>    
    public sealed class StorageCachedImage : BitmapSource
    {
        private readonly Uri uriSource;
        private readonly string filePath;

        private StorageCachedImage()
        {
            //创建缓存目录
            using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (!isolatedStorageFile.DirectoryExists(Keys.ChinaUnicomeCacheDirectory))
                {
                    isolatedStorageFile.CreateDirectory(Keys.ChinaUnicomeCacheDirectory);
                }
                isolatedStorageFile.Dispose();
            }
        }

        /// <summary>         
        /// 创建一个独立存储缓存的图片源         
        /// </summary>  
        /// <param name="uriSource"></param>        

        public StorageCachedImage(Uri uriSource)
            : this()
        {
            this.uriSource = uriSource;
            //文件路径
            //filePath =  Path.Combine(CacheDirectory, uriSource.AbsolutePath.TrimStart('/').Replace('/', '_'));
            //
            string filename = string.Format("image_{0}_{1}", MD5.GetMd5String(uriSource.AbsoluteUri), uriSource.AbsolutePath.TrimStart('/').Replace('/', '_'));
            //int lastIndexOf = uriSource.AbsolutePath.LastIndexOf(".");
            //string extendName = string.Empty;
            //if (lastIndexOf >= 0)
            //{
            //   extendName= uriSource.AbsolutePath.Substring(lastIndexOf);
            //}
            //string filename = string.Format("image_{0}{1}", MD5.GetMd5String(uriSource.AbsoluteUri), extendName);
            //
            filePath = Path.Combine(Keys.ChinaUnicomeCacheDirectory, filename);
            OpenCatchSource();
        }



        /// <summary>         
        /// 打开缓存源         
        /// </summary>
        private void OpenCatchSource()
        {
            bool exist;
            using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
            {
                exist = isolatedStorageFile.FileExists(filePath);
            }
            if (exist)
            {
                SetCacheStreamSource();
            }
            else
            {
                SetWebStreamSource();
            }
        }

        /// <summary>         
        /// 设置缓存流到图片        
        /// </summary> 
        private void SetCacheStreamSource()
        {
            try
            {
                using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
                using (var stream = isolatedStorageFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
                {
                    if (stream != null && stream.Length > 1)//图片不存在服务器，但httpWebRequest.EndGetResponse返回的ContentLength长度为1
                    {
                        SetSource(stream);
                    }
                    else
                    {
                        try
                        {
                            //404.jpg的Build类型是resource
                            StreamResourceInfo resourceInfo = Application.GetResourceStream(new System.Uri(Keys.RESOURCE_ASSEMBLYNAME + "/Images/404.jpg", UriKind.Relative));
                            //BitmapImage image = new BitmapImage();
                            //image.SetSource(resourceInfo.Stream);
                            SetSource(resourceInfo.Stream);
                        }
                        catch { }
                    }
                    stream.Close();
                    stream.Dispose();
                }
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.Message, typeof(StorageCachedImage), MethodBase.GetCurrentMethod());
                IsolatedStorageSettingHelper.RemoveIsolateStorageByKey(filePath);
            }
        }

        /// <summary>        
        /// 下载Uri中的图片         
        /// </summary>
        private void SetWebStreamSource()
        {
            HttpWebRequest httpWebRequest = null;
            try
            {
                httpWebRequest = (HttpWebRequest)WebRequest.Create(uriSource);
                httpWebRequest.AllowReadStreamBuffering = true;
                //httpWebRequest.BeginGetResponse(ResponseCallBack, httpWebRequest);
                httpWebRequest.BeginGetResponse(delegate(IAsyncResult asyncResult)
                {
                    if (httpWebRequest == null) return;
                    try
                    {
                        var response = httpWebRequest.EndGetResponse(asyncResult);
                        if (response == null)
                        {
                            LogHelper.LogError("文件不存在" + uriSource);
                            try
                            {
                                //404.jpg的Build类型是resource
                                StreamResourceInfo resourceInfo = Application.GetResourceStream(new System.Uri(Keys.RESOURCE_ASSEMBLYNAME + "/Images/UserCenter/Active_404.jpg", UriKind.Relative));
                                SetSource(resourceInfo.Stream);
                            }
                            catch { }
                        }
                        else
                        {
                            using (var stream = response.GetResponseStream())
                            using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
                            using (var fileStream = isolatedStorageFile.OpenFile(filePath, FileMode.OpenOrCreate, FileAccess.Write))
                            {
                                stream.CopyTo(fileStream);
                                fileStream.Close();
                                fileStream.Dispose();
                            }
                            Dispatcher.BeginInvoke(SetCacheStreamSource);
                        }
                    }
                    catch (Exception err)
                    {
                        LogHelper.LogError(err.Message + Environment.NewLine + uriSource, typeof(StorageCachedImage), MethodBase.GetCurrentMethod());
                    }
                }, httpWebRequest);
            }
            catch (Exception err)
            {
                if (httpWebRequest != null)
                {
                    httpWebRequest.Abort();
                }
                LogHelper.LogError("loading imagesource data has error:\t" + err.ToString() + Environment.NewLine + uriSource, this.GetType(), MethodBase.GetCurrentMethod());
            }
        }


        /// <summary>         
        /// 下载回调         
        /// </summary>  
        /// <param name="asyncResult"></param>      

        private void ResponseCallBack(IAsyncResult asyncResult)
        {
            var httpWebRequest = asyncResult.AsyncState as HttpWebRequest;
            if (httpWebRequest == null) return;
            try
            {
                var response = httpWebRequest.EndGetResponse(asyncResult);
                using (var stream = response.GetResponseStream())
                using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
                using (var fileStream = isolatedStorageFile.OpenFile(filePath, FileMode.OpenOrCreate, FileAccess.Write))
                {
                    stream.CopyTo(fileStream);
                    fileStream.Close();
                    fileStream.Dispose();
                }
                Dispatcher.BeginInvoke(SetCacheStreamSource);
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.Message, typeof(StorageCachedImage), MethodBase.GetCurrentMethod());
            }

        }
    }
}
